package com.jadows.tdog.server;

import cn.hutool.core.util.StrUtil;
import com.jadows.tdog.enums.ConnectStateEnum;
import com.jadows.tdog.server.option.ChatServerOption;
import com.jadows.tdog.server.option.ServerOption;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import lombok.extern.slf4j.Slf4j;

/**
 * @author taojiacheng
 */
@Slf4j
public class NettyChatServer extends AbstractNettyChatServer {

    private Channel channel;

    public NettyChatServer(ChatServerOption option) {
        super(option);
    }

    @Override
    protected void doStart() {
        log.info("chat server will start ...");
        if (option != null) {
            ServerOption serverOption = option.serverOption();
            if (serverOption.state() == ConnectStateEnum.INIT) {
                ChannelFuture ignored = doBind(serverOption);
            }
        }
    }

    /**
     * 绑定端口
     */
    protected ChannelFuture doBind(ServerOption serverOption) {
        log.info("start bind server [{}:{}] ...", serverOption.host(), serverOption.port());
        serverOption.addConnectTimes();
        serverOption.state(ConnectStateEnum.CONNECTING);

        ChannelFuture channelFuture;
        if (StrUtil.isBlank(serverOption.host())) {
            // 同步等待绑定成功
            channelFuture = bootstrap.bind(serverOption.port()).syncUninterruptibly();
        } else {
            channelFuture = bootstrap.bind(serverOption.host(), serverOption.port()).syncUninterruptibly();
        }
        if (channelFuture != null && channelFuture.isSuccess()) {
            //获取通道
            channel = channelFuture.channel();
            notifyStarted();
            log.info("chat server start success, listen port on {}", serverOption.port());
        } else {
            log.info("chat server start fail");
        }
        return channelFuture;
    }

    @Override
    protected void doStop() {
        log.info("chat server will stop ...");
        if (option != null) {
            channel.close();
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
            notifyStopped();
        }
    }

}
